#ifndef RTSP_PROXY_CLIENT_H
#define RTSP_PROXY_CLIENT_H

#include "rtsp_packet_parser.h"
#include "rtsp_proxy_type.h"
#include "udp_pipe.h"
#include "stream_task.h"

/**
 * @brief 连接代理,代理播放器向摄像机发起连接
 */
class RTSPProxyClient
{
public:
    /**
     * @details 连接事件回调
     */
    typedef void (*connect_cb)(rtsp::ConnectEnum type, void* arg);

    /**
     * @details RTSP方法回调
     */
    typedef void (*method_cb)(rtsp::RtspMethodEnum type, char *msg, void* arg);
    /**
     * @brief RTSPProxyClient
     * @param eb event_base
     * @param camera_host
     * @param camera_port
     * @param player_host
     */
    RTSPProxyClient(struct event_base* eb, const char* camera_host, int camera_port, const char* player_host);
    /**
     * @brief Connect 连接，完成后触发回调
     * @param connect_cb
     * @param cbarg
     */
    void Connect(connect_cb connect_cb, void *cbarg);
    /**
     * @brief ExecuteMethod 执行RTSP握手过程
     * @param msg
     * @param method_cb
     * @param cbarg
     * @return
     */
    int ExecuteMethod(const char* msg, method_cb method_cb, void *cbarg);
    virtual ~RTSPProxyClient();
private:
    /**
     * @brief OnRead 客户端读事件
     * @param bev
     * @param ctx
     */
    static void OnRead(struct bufferevent *bev, void *ctx);
    /**
     * @brief OnWrite 客户端写事件
     * @param bev
     * @param ctx
     */
    static void OnWrite(struct bufferevent *bev, void *ctx);
    /**
     * @brief OnEvent 事件回调
     * @param bev
     * @param what
     * @param ctx
     */
    static void OnEvent(struct bufferevent *bev, short what, void *ctx);
    rtsp::RtspMethodEnum GetRtspMethodName(const char *in);
    /**
     * @brief Options方法
     */
    int OptionsMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief Describe方法
     */
    int DescribeMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief Setup方法
     */
    int SetupMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief Play方法
     */
    int PlayMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief Teardown方法
     */
    int TeardownMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief GetParameter方法
     */
    int GetParameterMethod(const char* msg, method_cb method_cb, void *cbarg);
    /**
     * @brief 发送报文
     * @param msg
     * @return
     */
    int SendTo(const char* msg);
    rtsp::RtspMethodEnum current_method_;
    int connect_port_;
    struct event_base* eb_;
    struct bufferevent* bev_;
    connect_cb conn_cb_; //
    method_cb event_cb_;
    void* conn_cbarg_;
    void* event_cbarg_;
    RTSPPacketParser parser_;
    // 端口和地址信息
    rtsp::RTSPPort player_ports_;
    rtsp::RTSPPort player_proxy_ports_;
    rtsp::RTSPPort camera_ports_;
    rtsp::RTSPPort camera_proxy_ports_;
    char player_host_[16] = {0};
    char camera_host_[16] = {0};
    // 管线任务
    StreamTask *stream_task_ = nullptr;
};

#endif // RTSP_PROXY_CLIENT_H
